package com.purchase.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.purchase.entity.AppUser;
import com.purchase.entity.InviteCode;
import com.purchase.entity.WxUser;
import com.purchase.mapper.AppUserMapper;
import com.purchase.mapper.InviteCodeMapper;
import com.purchase.mapper.WxUserMapper;
import com.purchase.service.InviteCodeService;
import com.purchase.util.InviteCodeUtil;
import com.purchase.util.LogInfo;
import com.purchase.util.RequestForm;
import com.purchase.util.ResponseForm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import tk.mybatis.mapper.entity.Example;

import java.util.*;

@Slf4j
@Service
public class InviteCodeServiceImpl implements InviteCodeService {

	@Autowired
	private InviteCodeMapper inviteCodeMapper;

	@Autowired
	AppUserMapper appUserMapper;

	@Autowired
	WxUserMapper wxUserMapper;

	@Override
	public ResponseForm createCode(RequestForm param) {
		ResponseForm result = new ResponseForm();
		Map<String, Object> paramMap = (Map<String, Object>) param.getData();
		try {
			// 创建者
			String wxUid = (String) paramMap.get("wxUid");
			// 生成个数
			String num = (String) paramMap.get("num");
			// 邀请码级别，0：父级，1：子级
			String createClass = (String) paramMap.get("class");
			if (!StringUtils.isNotBlank(wxUid) || !StringUtils.isNotBlank(num)
					|| !StringUtils.isNotBlank(createClass)) {
				result.setStatus(false);
				result.setMessage(LogInfo.PARAM_ERROR);
				log.error(LogInfo.PARAM_ERROR);
				return result;
			}

			ArrayList<String> codes = this.generateCode(wxUid, num, createClass);
			if (codes == null) {
				result.setStatus(false);
				result.setMessage("该用户:" + wxUid + "未关联邀请码，无法创建下级邀请码");
				log.error("该用户:" + wxUid + "未关联邀请码，无法创建下级邀请码");
				return result;
			}

			result.setData(codes);
		} catch (Exception e) {
			result.setStatus(false);
			result.setMessage(LogInfo.ERROR);
			log.error("生成邀请码error", e);
		}

		return result;
	}

	@Override
	public ResponseForm getCode(RequestForm param) {
		ResponseForm result = new ResponseForm();
		Map<String, Object> paramMap = (Map<String, Object>) param.getData();
		try {
			String wxUid = (String) paramMap.get("wxUid");
			if (!StringUtils.isNotBlank(wxUid)) {
				result.setStatus(false);
				result.setMessage(LogInfo.PARAM_ERROR);
				log.error(LogInfo.PARAM_ERROR);
				return result;
			}

			com.purchase.util.Page.parsePage(paramMap);
			Page<Object> pageHelper = PageHelper.startPage((int) paramMap.get("page"), (int) paramMap.get("size"));
			List<InviteCode> inviteCodes = inviteCodeMapper.getInviteCodeList(wxUid);
			result.setData(inviteCodes);
			result.setTotal((int) pageHelper.getTotal());
		} catch (Exception e) {
			result.setStatus(false);
			result.setMessage(LogInfo.ERROR);
			log.error("查看邀请码error", e);
		}
		return result;
	}

	@Override
	public ArrayList<String> generateCode(String wxUid, String num, String createClass) {
		int createNum = Integer.parseInt(num);

		Integer parentId = 0;
		if ("0".equals(createClass)) {
			// 如果创建父级邀请码，则 parentId=0
			parentId = 0;
		} else if ("1".equals(createClass)) {
			// 如果创建子级邀请码，则 parentId=该用户所关联的inviteCodeId
			Example example = new Example(InviteCode.class);
			Example.Criteria criteria = example.createCriteria();
			criteria.andEqualTo("wxUid", wxUid);
			List<InviteCode> inviteCodes = inviteCodeMapper.selectByExample(example);
			if (inviteCodes.size() == 0) {
				return null;
			}
			parentId = inviteCodes.get(0).getId();
		}

		// 生成邀请码
		ArrayList<InviteCode> inviteCodes = new ArrayList<>();
		ArrayList<String> codes = new ArrayList<>();
		// 入库邀请码
		for (int i = 0; i < createNum; i++) {
			String code = InviteCodeUtil.generateCode(6);
			int countCode = inviteCodeMapper.getCountCode(code);
			if (countCode > 0) {
				createNum++;
				continue;
			}
			InviteCode inviteCode = new InviteCode();
			inviteCode.setInviteCode(code);
			inviteCode.setCreateWxUid(wxUid);
			inviteCode.setParentId(parentId);
			inviteCodes.add(inviteCode);
			codes.add(code);
		}
		inviteCodeMapper.insertCodeBatch(inviteCodes);
		return codes;
	}

	@Override
	public void useCode(String wxUid, String inviteCode) {
		inviteCodeMapper.disableInviteCode(wxUid, inviteCode);
	}

	@Transactional
	@SuppressWarnings({ "unused", "rawtypes" })
	@Override
	public ResponseForm bindParentInviteCode(RequestForm param) {
		ResponseForm result = new ResponseForm();
		if (param.getData() != null) {
			Map paramMap = (Map) param.getData();
			String tradeType = (String) paramMap.get("tradeType");
			if (!"APP".equals(tradeType)) {
				result.setCode("400");
				result.setMessage("不支持此平台");
				result.setStatus(false);
				return result;
			}
			String parentInviteCode = (String) paramMap.get("parentInviteCode");
			String wxUid = (String) paramMap.get("wxUid");
			try {
				AppUser parent = new AppUser();
				parent.setInviteCode(parentInviteCode);
				parent = appUserMapper.selectOne(parent);
				if (parent == null) {
					result.setCode("400");
					result.setMessage("邀请码无效");
					result.setStatus(false);
					return result;
				}
				AppUser appUser = new AppUser();
				appUser.setWxUid(wxUid);
				appUser = appUserMapper.selectOne(appUser);
				if (appUser == null) {
					result.setCode("400");
					result.setMessage("用户不存在");
					result.setStatus(false);
					return result;
				} else if (StringUtils.isNotBlank(appUser.getParentInviteCode())) {
					result.setCode("400");
					result.setMessage("该用户已绑定过推广码");
					result.setStatus(false);
					return result;
				}
				appUser.setParentInviteCode(parentInviteCode);
				appUserMapper.updateByPrimaryKeySelective(appUser);
				/*app推广码绑定成功后,同步更新该用户小程序账号的推广码*/
				Example example = new Example(WxUser.class);
				example.createCriteria().andEqualTo("unionId", appUser.getUnionId());
				WxUser wxUser = new WxUser();
				wxUser.setInviteCode(parentInviteCode);
				wxUserMapper.updateByExampleSelective(wxUser,example);
			} catch (Exception e) {
				result.setStatus(false);
				result.setCode("400");
				result.setMessage("参数错误");
				log.error("数据库访问错误", e);
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
		return result;
	}

	@Override
	public ResponseForm bindInviteCodeByMiniProgram(RequestForm param) {
		ResponseForm result = new ResponseForm();
		if (param.getData() != null) {
			Map paramMap = (Map) param.getData();
			String inviteCode = (String) paramMap.get("inviteCode");
			String wxUid = (String) paramMap.get("wxUid");
			if (StringUtils.isBlank(inviteCode) || StringUtils.isBlank(wxUid)) {
				result.setCode("400");
				result.setStatus(false);
				result.setMessage("参数不能为空");
				return result;
			}
			try {
				WxUser wxUser = new WxUser();
				wxUser.setWxUid(wxUid);
				wxUser = wxUserMapper.selectOne(wxUser);
				if (wxUser == null) {
					result.setCode("400");
					result.setStatus(false);
					result.setMessage("用户不存在");
					return result;
				} else if (StringUtils.isNotBlank(wxUser.getInviteCode())) {
					result.setCode("400");
					result.setStatus(false);
					result.setMessage("该用户已绑定过邀请码");
					return result;
				}
				wxUser.setInviteCode(inviteCode);
				wxUserMapper.updateByPrimaryKeySelective(wxUser);
				result.setCode("200");
				result.setStatus(true);
				result.setMessage("绑定邀请码成功");
			} catch (Exception e) {
				result.setStatus(false);
				result.setCode("400");
				result.setMessage("参数错误");
				log.error("数据库访问错误", e);
			}
		}
		return result;
	}

}
